//
//  main.m
//  C06_结构体
//
//  Created by dllo on 15/11/24.
//  Copyright © 2015年 dllo. All rights reserved.
//

#import <Foundation/Foundation.h>

struct ArrayStruct{
    int array[20];
    
};
typedef struct ArrayStruct ArrStruct;


/* typedef 将结构体类型重定义 */
struct ClassRoom {
    float area;
    int floor;
};

typedef struct ClassRoom ClassRoom;

typedef struct Computer {
    float cpu;
    char color[20];
}Computer; /** 此处的Computer为新的类型名 */



/**  第一种结构体定义变量写法. 通常使用这种方法定义结构体*/
#if 1
struct Teacher {
    char name[10];
    int age;
    float weight;
    ClassRoom classroom;/* 结构体嵌套 */
};
typedef struct Teacher Teacher;

/** 第二种结构体变量的写法 */
struct Driver {
    char name[20];
    char sex;
}dri1; /** 此处的dri1是一个变量   可以写多个变量  用逗号隔开*/
typedef struct Driver Driver;
/** 第三种结构体变量的写法, 次写法成为匿名结构体 */
struct  {
    char name[20];
    int age;
}englishTeacher;/** englishTeacher 为变量名 */
#endif








int main(int argc, const char * argv[]) {

# pragma mark - 知识点1 结构体定义
    {
#if 0
        /** 结构体语法
         * struct 结构体名{
              类型  成员名;
              类型  成员名;
              .....
           };
         *
         */
        
        /** 定义一个结构体 
         * 说明 :
         * 其中 struct Student 相当于 int
         *      stu1 相当于 a
         */
        struct Student {
            char name[20];
            int age;
            int number;
            float weight;
        };
        /** 定义一个结构体变量 */
        /** 通常,结构体在函数的外面定义. 详见main函数上面代码 */
        struct Student stu1 = {"Tom", 19, 1, 56.3};
        struct Student stu2 = {"James", 22, 2, 75.6};
        struct Student stu3 = {"Amy", 30, 3, 60};
        
        struct Teacher tea1 = {"Lili", 25, 55.5};
        
//      dri1 = {"Tom",'m'}; /** 结构体变量不能这样整体赋值,只能成员变量单独赋值*/
//      dri1.name = "Tom"; /** 注意,  成员变量如果是字符串,不能直接赋值,  需腰通过strcpy 字符拷贝函数 */
        strcpy(dri1.name, "Tom");
        dri1.sex = 'm';
        
        strcpy(englishTeacher.name,"Macal");
        englishTeacher.age = 35;
#endif
    }
    
#pragma mark - 练习
    
# pragma mark - 知识点2 用typedef定义结构体类型
    {
        /** typedef 的目的: 为了简化类型
         *  例如: struct Teacher 简化为 Teacher
         *       int [] 简化为 Array
         *  typedef 适用于任何类型,即可以将任何类型重定义
         */
        /** 详见main 函数上面代码部分*/
        
        ClassRoom class1= {100, 3};
        
        Computer pc1 = {1.5, "white"};
        
    }
    
#pragma mark - 练习
    
    
# pragma mark - 知识点3 结构体变量赋值
    {
#if 0
    Teacher tea1 = {"Wang",30,60};
    
    Teacher tea2 = tea1; /** 结构体变量可以直接赋值 */
    
    printf("name = %s\n", tea2.name);
    printf("age = %d\n", tea2.age);
    printf("weight = %.2f\n", tea2.weight);
#endif
        
    /** 数组变量不能直接赋值 */
        int array[5] = {3, 5, 2, 1, 4};
        int array2[5] = {};
        
//        array2 = array /** 数组变量不能直接赋值 */
        
        /** 小技巧: 把数组作为结构体的一个成员, 通过结构体直接赋值, 实现数组赋值 */
        
        ArrStruct struct1 = {{1, 2, 4, 5}};
        ArrStruct struct2 = struct1;
        
        for (int i = 0; i < 4; i++) {
            printf("%d ", struct2.array[i]);
        }
        
    }
#pragma mark - 练习
    
    
# pragma mark - 知识点4 结构体内存的占用
    {
#if 0
        Teacher tea3 = {"Lili",20, 50};
        printf("size:%lu\n",sizeof(tea3));
#endif
    }
    
# pragma mark - 练习
    
# pragma mark - 知识点5 结构体嵌套
    {
    /** 详见 main函数上面的结构体定义部分*/
    
    
    
    }
    
# pragma mark - 知识点6 结构体数组
    {
        /**  
         * 结构体数组,就是数组中的元素类型为结构体类型
         * 注意: 一个数组中的结构体类型要相同
         */
        
        Driver driver1 = {"Tom", 'm'};
        Driver driver2 = {"Tom2", 'm'};
        
        Computer computer1 = {3.5, "white"};
        Computer computer2 = {3.2, "gray"};
        
        /** 定义一个结构体数组*/
        
//        Driver arrDriver[5] = {driver1, driver2};/* 结构体数组中的结构体类型必须相同 */
        
    }
    
    
    
    return 0;
}
